﻿
/*
*      
*          ┌─┐       ┌─┐
*       ┌──┘ ┴───────┘ ┴──┐
*       │                 │
*       │       ───       │
*       │  ─┬┘       └┬─  │
*       │                 │
*       │       ─┴─       │
*       │                 │
*       └───┐         ┌───┘
*           │         │
*           │         │
*           │         │
*           │         └──────────────┐
*           │                        │
*           │                        ├─┐
*           │                        ┌─┘    
*           │                        │
*           └─┐  ┐  ┌───────┬──┐  ┌──┘         
*             │ ─┤ ─┤       │ ─┤ ─┤         
*             └──┴──┘       └──┴──┘ 
*                 神兽保佑 
*                 代码无BUG! 
*  Author shang
*  2022-07-21 15:25:05
*/

using System.Text.Json;
using Autofac.Annotation;
using Microsoft.Extensions.Configuration;
using TS.Common;
using TS.Memory;
using TS.Model;

namespace TS.Services;
[Component]
public class AuthorizationHandlerSerivce
{
    private  readonly IConfiguration _configuration;
    public AuthorizationHandlerSerivce(IConfiguration configuration)
    {
        _configuration = configuration;
    }
   
    //单位是分钟
    public string GenerateTokenCredential(string usermame, string usermsg)
    {
        //存在token
        if (DicMemCache.JwtTokens.IsExits(usermame))
        {
            var cachetoken = DicMemCache.JwtTokens.Get(usermame);
            var expire = JsonSerializer.Deserialize<JWTSecureDataHeader>(cachetoken.Split(".")[0].Base64Decode())
                .ExpireTime;
            ////未超时
            if ((DateTime.Now < DateTime.Parse(expire)))
            {
                return cachetoken;
            }
        }
        string result = string.Empty;
        var payload = usermsg;
        var ovetime= _configuration.GetSection("tokenovertime").Value.ToInt();
        //判断是否是7天免登陆
        var expiretime =  ovetime * 60 ;
        if (!payload.IsNullOrEmpty() && !payload.Equals("null"))
        {
            var dtNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var jwtHeader = JsonSerializer.Serialize(new JWTSecureDataHeader()
            {
                TimeStamp = dtNow, ExpireTime = DateTime.Now.AddSeconds(expiretime).ToString("yyyy-MM-dd HH:mm:ss")
            });
            var base64Payload = (payload).ConverBase64String();
            var encodedString = $"{(jwtHeader).ConverBase64String()}.{base64Payload}";
            var signature = (encodedString).HMACSHA256(dtNow + Global.sacreatekey + dtNow);
            result = $"{encodedString}.{signature}";
            //token 放入缓存
            DicMemCache.JwtTokens.Set(usermame, result);
        }

        return result;
    }
    
    
    /// <summary>
    /// 验证token 
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public (bool, string) ValidateJWTAuthentication(string token)
    {
        bool isSuccess = false;
        string resultMsg = "";
        if (token == null || token == "")
        {
            resultMsg = "没有签名！";
            return (isSuccess, resultMsg);
        }

        var jwtToken = token.Split('.');
        //token 格式
        if (jwtToken.Length != 3)
        {
            resultMsg = "Token格式不正确!";
            return (isSuccess, resultMsg);
        }
        var playlod = JsonSerializer.Deserialize<AuthenUser>(jwtToken[1].Base64Decode());
        var key = playlod.name;
        var cachetoken = DicMemCache.JwtTokens.Get(key);
        //签名不正确
        if (cachetoken != token)
        {
            resultMsg = "签名不正确!";
            return (isSuccess, resultMsg);
        }
        if (!DicMemCache.JwtTokens.IsExits(key))
        {
            resultMsg = "Token不存在!";
            return (isSuccess, resultMsg);
        }

        var expire = JsonSerializer.Deserialize<JWTSecureDataHeader>(cachetoken.Split(".")[0].Base64Decode())
            .ExpireTime;
        ////超时
        if ((DateTime.Now >DateTime.Parse(expire)))
        {
            resultMsg = "Token过期!";
            return (isSuccess, resultMsg);
        }
        isSuccess = true;
        return (isSuccess, resultMsg);
    }
}